package com.qd.admin.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cdqidi.dto.ApiResult;
import com.cdqidi.dto.ApiResultWrapper;
import com.cdqidi.dto.DelDTO;
import com.cdqidi.exception.ApiException;
import com.cdqidi.util.page.PageUtil;
import com.cdqidi.valid.group.DefaultGroup;
import com.cdqidi.valid.group.UpdateGroup;
import com.qd.common.sys.annotation.DataScope;
import com.qd.common.sys.annotation.OperatorInfo;
import com.qd.common.sys.domain.entity.person.PersonRoleAllDTO;
import com.qd.common.sys.domain.entity.role.RoleDTO;
import com.qd.common.sys.domain.entity.role.RoleMenuRelationsDTO;
import com.qd.common.sys.domain.entity.role.RolePersonRelationsDTO;
import com.qd.common.sys.enums.OperatorType;
import com.qd.system.service.role.RoleHoldService;
import com.qd.system.service.role.RoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 角色信息
 *
 * @author sjk
 */
@RestController
@Validated
@RequiredArgsConstructor
@Slf4j
public class RoleController {

    private final RoleService roleService;
    private final RoleHoldService roleHoldService;

    private static final String ROLE_ID_NULL_MSG = "角色ID不能为空";

    /**
     * 新增角色
     */
    @PreAuthorize("@ps.hasPermission('system:role:save')")
    @PostMapping(value = "/sys/sysRole/save")
    @OperatorInfo(title = "添加角色", operator = OperatorType.INSERT)
    public RoleDTO save(@Validated(DefaultGroup.class) @RequestBody RoleDTO roleDTO) {
        if (null == roleDTO.getAddTime()) {
            roleDTO.setAddTime(LocalDateTime.now());
        }
        return roleHoldService.saveRole(roleDTO);
    }

    /**
     * 修改角色
     */
    @PreAuthorize("@ps.hasPermission('system:role:edit')")
    @PutMapping(value = "/sys/sysRole/update")
    @OperatorInfo(title = "修改角色", operator = OperatorType.UPDATE)
    public ApiResultWrapper<Object> update(@Validated({UpdateGroup.class, DefaultGroup.class}) @RequestBody RoleDTO roleDTO) {
        if (null == roleDTO.getUpdateTime()) {
            roleDTO.setUpdateTime(LocalDateTime.now());
        }
        return roleHoldService.updateRole(roleDTO);
    }

    /**
     * 删除角色
     */
    @PreAuthorize("@ps.hasPermission('system:role:delete')")
    @DeleteMapping(value = "/sys/sysRole/delete")
    @OperatorInfo(title = "删除角色", operator = OperatorType.DELETE)
    public ApiResultWrapper<Object> deleteByRoleId(@Validated @RequestBody DelDTO<String> delDTO) {
        final List<String> ids = delDTO.getIds();
        if (ids.size() == 1) {
            roleHoldService.removeById(ids.get(0));
        } else {
            roleHoldService.removeByIds(ids);
        }
        return ApiResult.success("删除成功");
    }

    /**
     * 查看角色
     */
    @GetMapping(value = "/sys/sysRole/getById")
    public RoleDTO getById(@Validated @NotBlank(message = ROLE_ID_NULL_MSG) String roleId) {
        return roleHoldService.getByIdDto(roleId);
    }

    /**
     * 角色列表
     *
     * @return 列表
     */
    @GetMapping(value = "/sys/sysRole/page")
    public IPage<RoleDTO> page(RoleDTO roleDTO) {
        return roleService.page(PageUtil.buildPage(roleDTO), roleDTO);
    }

    /**
     * 全部角色
     *
     * @return 列表
     */
    @GetMapping(value = "/sys/sysRole/list")
    public List<RoleDTO> list(RoleDTO roleDTO) {
        return roleService.getListDto(roleDTO);
    }

    /**
     * 角色信息导出
     *
     * @param query 查询参数
     */
    @PreAuthorize("@ps.hasPermission('system:role:export')")
    @GetMapping(value = "/sys/sysRole/export")
    @OperatorInfo(title = "角色信息导出", operator = OperatorType.EXPORT)
    public void export(RoleDTO query) {
        long startTime = System.currentTimeMillis();
        roleService.export(query);
        long endTime = System.currentTimeMillis();
        log.info("角色信息导出,总耗时: {}s", (endTime - startTime) / 1000);
    }

    /**
     * 设置角色和菜单的关系
     */
    @PreAuthorize("@ps.hasPermission('system:role:setMenu')")
    @PutMapping(value = "/sys/sysRole/setRoleMenuRelations")
    @OperatorInfo(title = "设置角色和菜单的关系", operator = OperatorType.UPDATE)
    public ApiResultWrapper<Object> setRoleMenuRelations(@Validated(DefaultGroup.class) @RequestBody RoleMenuRelationsDTO roleMenuRelationsDTO) {
        final ApiResultWrapper<Object> result = roleHoldService.setRoleMenuRelations(roleMenuRelationsDTO);
        roleMenuRelationsDTO.freeData();
        return result;
    }

    /**
     * 设置角色和人员的关系
     */
    @PreAuthorize("@ps.hasPermission('system:role:setUser')")
    @PutMapping(value = "/sys/sysRole/setRolePersonRelations")
    @OperatorInfo(title = "设置角色和人员的关系", operator = OperatorType.UPDATE)
    public ApiResultWrapper<Object> setRolePersonRelations(@Validated(DefaultGroup.class) @RequestBody RolePersonRelationsDTO rolePersonRelationsDTO) {
        if (rolePersonRelationsDTO.getPersonList().isEmpty()) {
            return ApiResult.error("人员信息不能为空");
        }
        final ApiResultWrapper<Object> result = roleHoldService.setRolePersonRelations(rolePersonRelationsDTO);
        rolePersonRelationsDTO.freeData();
        return result;
    }

    /**
     * 删除角色和菜单的关系
     */
    @PreAuthorize("@ps.hasPermission('system:role:deleteRoleMenuRelations')")
    @DeleteMapping(value = "/sys/sysRole/deleteRoleMenuRelations")
    @OperatorInfo(title = "删除角色和菜单的关系", operator = OperatorType.DELETE)
    public ApiResultWrapper<Object> deleteRoleMenuRelations(@Validated({DefaultGroup.class, DefaultGroup.class}) @RequestBody RoleMenuRelationsDTO roleMenuRelationsDTO) {
        final ApiResultWrapper<Object> result = roleHoldService.deleteRoleMenuRelations(roleMenuRelationsDTO);
        roleMenuRelationsDTO.freeData();
        return result;
    }

    /**
     * 删除角色和人员的关系
     */
    @PreAuthorize("@ps.hasPermission('system:role:deleteRolePersonRelations')")
    @DeleteMapping(value = "/sys/sysRole/deleteRolePersonRelations")
    @OperatorInfo(title = "删除角色和人员的关系", operator = OperatorType.DELETE)
    public ApiResultWrapper<Object> deleteRolePersonRelations(@Validated(DefaultGroup.class) @RequestBody RolePersonRelationsDTO rolePersonRelationsDTO) {
        final ApiResultWrapper<Object> result = roleHoldService.deleteRolePersonRelations(rolePersonRelationsDTO);
        rolePersonRelationsDTO.freeData();
        return result;
    }


    /**
     * 角色和人员列表
     *
     * @return 列表
     */
    @GetMapping(value = "/sys/sysRole/rolePersonPage")
    @DataScope(orgAlias = "o")
    public IPage<PersonRoleAllDTO> rolePersonPage(PersonRoleAllDTO personRoleAllDTO) {
        if (!StringUtils.hasLength(personRoleAllDTO.getRoleId())) {
            throw new ApiException(ROLE_ID_NULL_MSG);
        }
        return roleHoldService.rolePersonPage(PageUtil.buildPage(personRoleAllDTO), personRoleAllDTO);
    }
}